<?php

namespace app\api\controller\v1;

use addons\cardocr\library\traits\Check;
use app\common\controller\Api;
use app\common\library\Sms;
use fast\Http;
use think\Db;
use think\Exception;
use think\exception\PDOException;
use think\Validate;

/**
 * 会员接口
 */
class User extends Api
{
    use Check;

    protected $noNeedLogin = ['login', 'KanKanYouMeiYouYunYanDeDingDan'];
    protected $noNeedRight = '*';
    public static $level = [null => '无', 1 => 'LV1', 2 => 'Lv2', 3 => 'LV3', 4 => 'LV4', 5 => 'LV5'];
    public static $gender = [1 => '男', 2 => '女', 3 => '未知'];

    public function _initialize()
    {
        parent::_initialize();
    }

    /**
     * 小程序登录
     * @param string $code code码
     */
    public function login()
    {
        if ($this->request->isGet()) {
            $code     = $this->request->param('code');
            $nickname = $this->request->param('nickname');
            $avatar   = $this->request->param('avatar');

            $code == null && $this->error('code 参数不能为空');
            $nickname == null && $this->error('nickname 参数不能为空');
            $avatar == null && $this->error('avatar 参数不能为空');

            $pay        = get_addon_config('epay');
            $app_id     = $pay['wechat']['miniapp_id'];
            $app_secret = $pay['wechat']['app_secret'];

            $get_result = (new Http)->get("https://api.weixin.qq.com/sns/jscode2session?appid=$app_id&secret=$app_secret&js_code=$code&grant_type=authorization_code");
            // 对JSON格式的字符串进行解码
            $array = json_decode($get_result, true);

            if (!empty($array['openid'])) {
                $find = Db::name('user')->where(['open_id' => $array['openid']])->field('id')->find();
                if ($find) { // 老用户
                    $user_id = $find['id'];
                    Db::startTrans();
                    try {
                        Db::name('user')->where(['open_id' => $array['openid']])->update([
                            'session_key' => $array['session_key'],
                            'nickname'    => $nickname,
                            'avatar'      => $avatar,
                        ]);
                        Db::commit();
                    } catch (\Exception $e) {
                        Db::rollback();
                        $this->error($e->getMessage());
                    }
                } else { // 新用户
                    $insert_data = [
                        'open_id'     => $array['openid'],
                        'createtime'  => time(),
                        'updatetime'  => time(),
                        'status'      => 1,
                        'session_key' => $array['session_key'],
                        'nickname'    => $nickname,
                        'avatar'      => $avatar,
                    ];
                    Db::startTrans();
                    try {
                        $user_id = Db::name('user')->insertGetId($insert_data);
                        Db::commit();
                    } catch (\Exception $e) {
                        Db::rollback();
                        $this->error($e->getMessage());
                    }
                }

                if ($this->auth->direct($user_id)) {
                    $this->success('登录成功', $this->auth->getUserinfo());
                } else {
                    $this->error($this->auth->getError());
                }
            } else {
                $this->error('登陆失败，请检查小程序配置');
            }
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 微信授权; 更新头像、昵称
     * @ApiMethod (GET)
     * @param string $nickname 昵称
     * @param string $avatar 头像地址
     */
    public function auth()
    {
        if ($this->request->isGet()) {
            $nickname = $this->request->param('nickname');
            $avatar   = $this->request->param('avatar');

            $nickname == null && $this->error('nickname 参数不能为空');
            $avatar == null && $this->error('avatar 参数不能为空');

            $data = ['nickname' => $nickname, 'avatar' => $avatar, 'updatetime' => time()];

            try {
                Db::name('user')->where(['id' => $this->auth->id])->update($data);
            } catch (PDOException $e) {
                $this->error($e->getMessage());
            } catch (Exception $e) {
                $this->error($e->getMessage());
            }
            $this->success('更新用户信息成功');
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 微信授权; 解密手机号
     * @ApiMethod (GET)
     * @param $encryptedData string 加密的信息
     * @param $iv string iv 向量
     */
    public function authPhone()
    {
        if ($this->request->isGet()) {

            $encryptedData = $this->request->param('encryptedData', false);
            $iv            = $this->request->param('iv', false);

            $encryptedData == false && $this->error('encryptedData 参数不得为空');
            $iv == false && $this->error('iv 参数不得为空');

            $find = Db::name('user')->where(['id' => $this->auth->id])->field('')->find();

            // 解密数据
            $result = json_decode(openssl_decrypt(base64_decode($encryptedData), "AES-128-CBC", base64_decode($find['session_key']), 1, base64_decode($iv)));

            if ($result) {
                try {
                    Db::name('user')->where(['id' => $this->auth->id])->update(['mobile' => $result->phoneNumber]);
                } catch (PDOException $e) {
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    $this->error($e->getMessage());
                }
                $this->success('解密成功', $result->phoneNumber);
            } else {
                $this->error('解密失败');
            }
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 快速打卡
     */
    public function clock()
    {
        $user = Db::name('order')
                  ->alias('o')
                  ->join('hotel h', 'h.id = o.hotel_id', 'left')
                  ->join('job j', 'j.id = o.job_id', 'left')
                  ->where(['o.user_id' => $this->auth->id, 'o.status' => ['in', '1,2,3']])
                  ->field('o.id,o.order_job_type as type,o.status,j.job_arrival_datetime as arrival,h.hotel_name as name,j.job_location as location')
                  ->find();
        if ($user) {
            $user['type_text']   = Job::$job_type[$user['type']];
            $user['status_text'] = Order::$status[$user['status']];
            $this->success('获取成功', $user);
        } else {
            $this->error('暂无订单信息');
        }
    }

    /**
     * 获取用户认证信息
     */
    public function getUserReal()
    {
        if ($this->request->isGet()) {

            $result                     = Db::name('user')->where(['id' => $this->auth->id])->field('username,number,card_up_image,card_down_image,mobile')->find();
            $result['card_up_image_']   = self::patchSingle($result['card_up_image']);
            $result['card_down_image_'] = self::patchSingle($result['card_down_image']);

            if ($result['number']) {
                $this->success('获取成功', $result);
            } else {
                $this->error('获取失败');
            }
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 实名认证
     */
    public function real()
    {
        if ($this->request->isPost()) {

            $user = $this->auth->getUser();

            $data['username']        = $this->request->param('username');
            $data['number']          = $this->request->param('number');
            $data['card_up_image']   = $this->request->param('card_up_image');
            $data['card_down_image'] = $this->request->param('card_down_image');
            $data['mobile']          = $this->request->param('mobile');
            $data['captcha']         = $this->request->param('captcha');

            $data['username'] == null && $this->error('请填写您的姓名');
            $data['number'] == null && $this->error('请输入身份证号');
            $data['card_up_image'] == null && $this->error('请上传身份证正面照');
            $data['card_down_image'] == null && $this->error('请上传身份证返面照');
            $data['mobile'] == null && $this->error('请填写手机号');
            $data['captcha'] == null && $this->error('请输入验证码');

            // 验证短信
            $sms = Sms::check($data['mobile'], $data['captcha'], 'send');
            !$sms && $this->error('验证码不正确');

            // 检测文件
            !file_isset($data['card_up_image']) && $this->error('身份证正面文件不存在');
            !file_isset($data['card_down_image']) && $this->error('身份证反面文件不存在');
//            file_size($data['card_up_image']) / 1024 / 1024 > 3 && $this->error('上传的文件超过了3M');

            // 腾讯OCR识别
            $front = $this->checkfront(cdnurl($data['card_up_image'], true));

            // 身份证正面 反面不认证
            if (is_array($front)) {
                if ($front['Name'] != $data['username']) $this->error('实名认证失败,姓名与身份证不符');
                if ($front['IdNum'] != $data['number']) $this->error('实名认证失败,身份证号与身份证不符');
            } else {
                $this->$front('实名认证失败');
            }

            try {
                Db::startTrans();
                $data['real'] = 1;
                $result       = $user->allowField(true)->save($data);
                if ($result == 0) {
                    Db::rollback();
                    $this->error('认证失败，数据库更新失败');
                }
                Db::commit();
            } catch (Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }

            $this->success('认证成功', ['username' => $data['username']]);
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 获取或者 编辑简历
     * 姓名在实名认证完成后不可更改
     */
    public function resume()
    {
        if ($this->request->isPost()) {
            $data['username']     = $this->request->param('username');
            $data['gender']       = $this->request->param('gender');
            $data['age']          = $this->request->param('age');
            $data['stature']      = $this->request->param('stature');
            $data['health']       = $this->request->param('health');
            $data['health_image'] = $this->request->param('health_image');
            $data['disease']      = $this->request->param('disease');
            $data['introduce']    = $this->request->param('introduce');

            $rule = [
                'username'     => 'require',
                'gender'       => 'require|in:1,2',
                'age'          => 'require',
                'stature'      => 'require',
                'health'       => 'require|in:1,2',
                'health_image' => 'requireIf:health,1',
                'disease'      => 'require|max:255',
//                'introduce'    => 'require|max:255',
            ];

            $message = [
                'username.require'       => '请填写姓名',
                'gender.require'         => '请选择性别',
                'gender.in'              => '性别字段选择有误',
                'age.require'            => '请输入年龄',
                'stature.require'        => '请输入身高',
                'health.require'         => '请选择是否有健康证',
                'health.in'              => '健康证字段选择有误',
                'health_image.requireIf' => '请上传健康证',
                'disease.require'        => '请输入您的病史，无疾病史请输入‘无’',
                'disease.max'            => '疾病史最多255字符',
//                'introduce.require'      => '请输入您的自我介绍',
//                'introduce.max'          => '自我介绍最多255字符',
            ];

            $validate = new Validate($rule, $message);
            !$validate->check($data) && $this->error($validate->getError());
            // 检测文件是否存在
            !file_isset($data['health_image']) && $this->error('上传的健康证文件不存在');

            Db::startTrans();
            try {
                $data['updatetime'] = time();
                $result             = Db::name('user')->where(['id' => $this->auth->id])->update($data);
                if ($result == 0) {
                    Db::rollback();
                    $this->error('更新失败');
                }
                Db::commit();
            } catch (Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }

            $this->success('编辑成功');
        } elseif ($this->request->isGet()) {
            $user = $this->auth->getUser();
            $user->visible(['username', 'gender', 'age', 'stature', 'health', 'health_image', 'disease', 'introduce']);
            $user                  = $user->toArray();
            $user['health_image_'] = self::patchSingle($user['health_image']);
            unset($user['url']);
            if ($user['username'] != null) {
                $this->success('获取成功', $user);
            } else {
                $this->error('获取失败');
            }
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 发送短信
     */
    public function sendSms()
    {
        if ($this->request->isGet()) {
            $mobile = $this->request->param('mobile');
            $mobile == null && $this->error('请输入您的手机号');
            strlen($mobile) != 11 && $this->error('手机号长度不正确');
            $match = preg_match('/^1[3|4|5|7|8][0-9]\d{4,8}$/i', $mobile);
            $match == 0 && $this->error('您输入的手机号不正确，请重新输入');

            $result = Sms::send($mobile, null, 'send');
            $result ? $this->success('发送成功') : $this->error('发送失败');
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 订单列表,详情,搜索
     */
    public function order()
    {
        if ($this->request->isGet()) {
            Order::$status[1] = '已报名，待确认';
            $status           = $this->request->param('status');
            $id               = $this->request->param('id');
            $key              = $this->request->param('key');

            ($status == null && $id == null && $key == null) && $this->error('status,id,key 至少传入一个参数');

            if ($id != null) {
                $result = Db::name('order')
                            ->alias('o')
                            ->join('hotel h', 'h.id = o.hotel_id', 'left')
                            ->join('job j', 'j.id = o.job_id', 'left')
                            ->field('o.id,h.id as hotel_id,o.user_id,o.order_job_type as type,o.status,j.job_arrival_datetime as arrival,h.hotel_name as name,j.job_location as location,j.job_route as route,j.job_condition as `condition`,o.createtime,o.number,o.price,o.user_first_time,o.user_second_time,o.confirm_renewal as renewal,o.time_hour,o.duration_hour')
                            ->find(['id' => $id]);
                if ($result) {
                    $result['user_id'] != $this->auth->id && $this->error('此订单不属于您');
                    $result['type_text']        = Job::$job_type[$result['type']];
                    $result['status_text']      = Order::$status[$result['status']];
                    $result['show']             = 1;
                    $result['createtime']       = date('Y年m月d日 H:i:s', $result['createtime']);
                    $result['user_first_time']  = $result['user_first_time'] ? date('Y-m-d H:i:s', $result['user_first_time']) : false;
                    $result['user_second_time'] = $result['user_second_time'] ? date('Y-m-d H:i:s', $result['user_second_time']) : false;
                    $result['clock']            = $result['user_first_time'] ? 2 : 1;
                    if ($result['user_second_time'] && $result['user_first_time']) {
                        $result['clock'] = 3;
                    }
                    $this->success('获取成功', $result);
                } else {
                    $this->error('获取失败，未找到记录');
                }
            } elseif ($status != null) {
                $where['o.user_id'] = $this->auth->id;
                if ($status == '0') {
                    $where['o.status'] = ['in', '1,2,4'];
                } else {
                    $where['o.status'] = $status;
                }

                $result = Db::name('order')
                            ->alias('o')
                            ->join('hotel h', 'h.id = o.hotel_id', 'left')
                            ->join('job j', 'j.id = o.job_id', 'left')
                            ->field('o.id,o.order_job_type as type,o.status,j.job_arrival_datetime as arrival,h.hotel_name as name,j.job_location as location,o.price,o.number')
                            ->where($where)
                            ->paginate(null, false, $this->paginate)
                            ->each(function ($item) {
                                $item['type_text']   = Job::$job_type[$item['type']];
                                $item['status_text'] = Order::$status[$item['status']];
                                $item['show']        = 1;
                                return $item;
                            });

                $this->success('获取成功', $result);
            } else {
                $result = Db::name('order')
                            ->alias('o')
                            ->join('hotel h', 'h.id = o.hotel_id', 'left')
                            ->join('job j', 'j.id = o.job_id', 'left')
                            ->field('o.id,o.order_job_type as type,o.status,j.job_arrival_datetime as arrival,h.hotel_name as name,j.job_location as location,o.price,o.number')
                            ->whereLike('o.number', '%' . $key . '%')
                            ->whereOr('j.job_name', 'like', '%' . $key . '%')
                            ->whereOr('h.hotel_name', 'like', '%' . $key . '%')
                            ->where(['o.user_id' => $this->auth->id, 'o.status' => ['in', '1,2,4']])
                            ->paginate(null, false, $this->paginate)
                            ->each(function ($item) {
                                $item['type_text']   = Job::$job_type[$item['type']];
                                $item['status_text'] = Order::$status[$item['status']];
                                $item['show']        = 1;
                                return $item;
                            });

                $this->success('获取成功', $result);
            }
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 调整延顺用工
     */
    public function renewal()
    {
        if ($this->request->isGet()) {
            $id = $this->request->param('id');

            ($id == null) && $this->error('id 参数不能为空');

            $find = Db::name('order')->where(['id' => $id])->find();

            if ($find) {
                $find['user_id'] != $this->auth->id && $this->error('不能更改他人订单');
                $find['status'] == 3 && $this->error('此订单已被停止，请及时联系客服人员处理！');

                $result = Db::name('order')
                            ->where(['id' => $id, 'user_id' => $this->auth->id])
                            ->update(['updatetime' => time(), 'confirm_renewal' => $find['confirm_renewal'] == 1 ? '2' : '1']);

                $result == 0 && $this->error('更新失败,没有记录被更新');
            } else {
                $this->error('更新失败，记录未找到');
            }

            $this->success('更新成功');
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 打卡 签到
     */
    public function attendance()
    {
        if ($this->request->isGet()) {
            $id       = $this->request->param('id');
            $location = $this->request->param('location');

            ($id == null) && $this->error('id 参数不能为空');
            ($location == null) && $this->error('location 参数不能为空');

            $find = Db::name('order')->where(['id' => $id])->find();

            if ($find) {
                $find['user_id'] != $this->auth->id && $this->error('不能更改他人订单');
                $find['status'] == 3 && $this->error('此订单已被停止，请及时联系客服人员处理！');

                // 判断是第几次打卡 第二次需要计算工时
                $data = [
                    'updatetime'          => time(),
                    'user_first'          => 1,
                    'user_first_time'     => time(),
                    'user_first_location' => $location
                ];
                if ($find['user_first'] == 1) {
                    // 计算工时
                    $duration_hour = intval((time() - $find['user_first_time']) / 1800) / 2;
                    $data          = [
                        'updatetime'           => time(),
                        'user_second'          => 1,
                        'user_second_time'     => time(),
                        'user_second_location' => $location,
                        'duration_hour'        => $duration_hour
                    ];
                } else { // 用户第一次打卡
                    // 判断打卡时间
                    $job = Db::name('job')->where(['id' => $find['job_id']])->find();
                    if ($job) {
                        if (strtotime($job['job_arrival_datetime']) > time() + 3600 * 4) $this->error('上岗前4小时才能打卡');
                    } else {
                        $this->error('打卡失败，招聘信息已失效');
                    }
                }
                $result = Db::name('order')
                            ->where(['id' => $id, 'user_id' => $this->auth->id])
                            ->update($data);

                $result == 0 && $this->error('打卡失败,没有记录被更新');
                $back['time'] = date("Y-m-d H:i:s");
                if ($find['user_first'] == 1) {
                    $back['number']        = 2;
                    $back['clock']         = 3;
                    $back['duration_hour'] = $data['duration_hour'];
                } else {
                    $back['number'] = 1;
                    $back['clock']  = 2;
                }
                $this->success('打卡成功', $back);
            } else {
                $this->error('打卡失败，记录未找到');
            }
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 更新手机号
     */
    public function setPhone()
    {
        if ($this->request->isGet()) {
            $data['mobile']  = $this->request->param('mobile');
            $data['captcha'] = $this->request->param('captcha');

            $data['mobile'] == null && $this->error('请填写手机号');
            $data['captcha'] == null && $this->error('请输入验证码');

            // 验证短信
            $sms = Sms::check($data['mobile'], $data['captcha'], 'send');
            !$sms && $this->error('验证码不正确');

            unset($data['captcha']);
            Db::name('user')->where(['id' => $this->auth->id])->update($data);
            $this->success('更新成功');
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 看看有没有顺延的订单
     */
    public function kanKanYouMeiYouYunYanDeDingDan()
    {
        if ($this->request->isGet()) {
            if ($this->auth->isLogin()) {
                $date   = date("Y-m-d", strtotime('+ 1day'));
                $result = Db::name('order')->where(['user_id' => $this->auth->id, 'order_job_date' => $date, 'is_renewal' => 1])->find();
                if ($result) {
                    $this->success('kanKanYouMeiYouYunYanDeDingDan', $result);
                } else {
                    $this->error('没有获取到');
                }
            }
            $this->error('没有登录');
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }
}
